package com.googlecode.felicalib.sample.client;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.felicalib.sample.Felica;
import com.googlecode.felicalib.sample.exception.FelicaException;
import com.googlecode.felicalib.sample.polling.FelicaPollingHost;

/**
 * java application (System Tray).
 *
 * @author o.tanaka
 */

public class FelicaTray {

    /**
     * long serialVersionUID
     */
    private static final long serialVersionUID = 8064531557020146279L;
    /**
     * ロギングインスタンス.
     */
    private static final Log LOG = LogFactory.getLog(FelicaTray.class);

    private static SystemTray systemTray = SystemTray.getSystemTray();
    private static Felica felica = null;
    static {
        try {
            FelicaTray.felica = new Felica();
        } catch (final FelicaException e) {
            System.err.println(Messages.getString("FelicaTray.not_acces"));
            System.exit(-1);
        }
    }

    private static final int POLLING = 0;
    /**
     * FelicaTray NOT_POLLING.
     */
    public static final int NOT_POLLING = 1;

    /**
     * @param args
     *            パラメータ
     */
    public static final void main(final String[] args) {
        new FelicaTray();
    }

    private TrayIcon trayicon = null;

    /**
     * コンストラクタ.
     */
    public FelicaTray() {
        this.menuSet(FelicaTray.POLLING);
        FelicaPollingHost.polling(
                FelicaTray.felica, Felica.WILDCARD, FelicaTray.POLLING);
        this.trayicon.displayMessage(
                Messages.getString("FelicaTray.polling_start"),
                Messages.getString("FelicaTray.msg_polling_start"),
                TrayIcon.MessageType.INFO);
    }

    /**
     * @param aServiceCode
     *            serviceCode
     * @param anAddrInt
     *            addr
     * @return data
     */
    public final String getData(
            final int aServiceCode, final int anAddrInt) {
        return FelicaPollingHost.read(aServiceCode, (byte) anAddrInt);
    }

    /**
     * @return felica
     */
    public final Felica getFelica() {
        return FelicaTray.felica;
    }

    /**
     * @return IDm
     */
    public final String getIDm() {
        return FelicaPollingHost.getIDm();
    }

    /**
     * @return PMm
     */
    public final String getPMm() {
        return FelicaPollingHost.getPMm();
    }

    /**
     * @return systemTray
     */
    public final SystemTray getSystemTray() {
        return FelicaTray.systemTray;
    }

    /**
     * @return trayicon
     */
    public final TrayIcon getTrayicon() {
        return this.trayicon;
    }

    private PopupMenu makePopUp(final int stts) {
        final PopupMenu menu = new PopupMenu();
        MenuItem pollingMenu = null;
        switch (stts) {
        case 0:
            pollingMenu =
                new MenuItem(
                    Messages.getString("FelicaTray.polling_stop_menu"));
            pollingMenu.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent ev) {
                    FelicaTray.this.trayicon.displayMessage(Messages
                            .getString("FelicaTray.title"),
                            Messages.getString("FelicaTray.msg_polling_stop"),
                            TrayIcon.MessageType.INFO);
                    FelicaTray.this.trayicon.setPopupMenu(FelicaTray.this
                            .makePopUp(FelicaTray.NOT_POLLING));
                    FelicaPollingHost.polling(
                                FelicaTray.felica, Felica.WILDCARD,
                                FelicaTray.NOT_POLLING);

                }
            });
            break;
        case 1:
            pollingMenu =
                new MenuItem(Messages
                        .getString("FelicaTray.polling_start_menu"));
            pollingMenu.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent ev) {
                    FelicaTray.this.trayicon.displayMessage(
                            Messages.getString("FelicaTray.polling_start"),
                            Messages.getString("FelicaTray.msg_polling_start"),
                            TrayIcon.MessageType.INFO);
                    FelicaTray.this.trayicon.setPopupMenu(FelicaTray.this
                            .makePopUp(FelicaTray.POLLING));
                    FelicaPollingHost.polling(
                                FelicaTray.felica, Felica.WILDCARD,
                                FelicaTray.POLLING);
                }
            });
            break;

        default:
            pollingMenu =
                new MenuItem(Messages
                        .getString("FelicaTray.polling_start_menu"));
            pollingMenu.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent ev) {
                    FelicaTray.this.trayicon.displayMessage(
                            Messages.getString("FelicaTray.polling_start"),
                            Messages.getString("FelicaTray.msg_polling_start"),
                            TrayIcon.MessageType.INFO);
                    FelicaTray.this.trayicon.setPopupMenu(FelicaTray.this
                            .makePopUp(FelicaTray.POLLING));
                    FelicaPollingHost.polling(
                                FelicaTray.felica, Felica.WILDCARD,
                                FelicaTray.POLLING);
                }
            });
            break;
        }
        menu.add(pollingMenu);
        final MenuItem open =
            new MenuItem(Messages.getString("FelicaTray.show_menu"));
        open.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
                final FelicaJFrame jFrame = new FelicaJFrame();
                jFrame.setIDm(FelicaTray.this.getIDm());
                jFrame.setPMm(FelicaTray.this.getPMm());
                jFrame.setVisible(true);
            }
        });
        menu.add(open);
        menu.add(new MenuItem("-"));
        final MenuItem quit =
            new MenuItem(Messages.getString("FelicaTray.exit"));
        quit.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
                FelicaPollingHost.polling(
                        FelicaTray.felica, Felica.WILDCARD,
                        FelicaTray.NOT_POLLING);
                FelicaTray.felica.close();
                FelicaTray.systemTray.remove(FelicaTray.this.trayicon);
            }
        });
        menu.add(quit);

        return menu;
    }

    /**
     * TrayMenu setting.
     *
     * @param stts
     *            stts
     */
    private void menuSet(final int stts) {
        final URL url =
            this.getClass()
                    .getResource(Messages.getString("FelicaTray.images"));
        try {
            final Image img = ImageIO.read(url);
            FelicaTray.this.trayicon =
                new TrayIcon(img, Messages.getString("FelicaTray.title"),
                    this.makePopUp(stts));
            FelicaTray.systemTray.add(FelicaTray.this.trayicon);
        } catch (final IOException e) {
            FelicaTray.LOG.error("IOException:", e);
        } catch (final AWTException e) {
            FelicaTray.LOG.error("AWTException:", e);
        }
    }

    /**
     * @param aServiceCode
     *            serviceCode
     * @param anAddrInt
     *            addr
     * @param aData
     *            data
     * @return boolean
     */
    public boolean setCard(
            final int aServiceCode,
            final int anAddrInt,
            final byte[] aData) {
        return FelicaPollingHost.write(aServiceCode, (byte) anAddrInt, aData);
    }

    /**
     * @param aTrayicon
     *            the trayicon to set
     */
    public final void setTrayicon(final TrayIcon aTrayicon) {
        this.trayicon = aTrayicon;
    }

}
